#include "constants.h";

XfMissionChapterExecute={
	private ["_chapter_succeeded"];
	diag_log "";
	diag_log "=========================================================================";
	diag_log "                             CHAPTER 1                                   ";
	diag_log "=========================================================================";
	diag_log "";
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Starting Chapter","_last_random_reinforcement","_random_reinf_diff","_reinforcement_power"];
	DM_Mission_ArtilleryVariables = [];
	DM_Mission_Chapter_CanRun = True;
	DM_Mission_Chapter_Runs = True;
	DM_Mission_Chapter_Success = 0;
	call XfMissionChapterSetup;
	_chapter_succeeded = false;
	if (!DM_Mission_Mission_CanRun) exitWith {diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Mission canceled!"];};
	
	// We need the castle infos to send paras to the right place :)
	_random_spot = DM_Chapter_Location;
	_random_spot_pos = _random_spot select XF_MAP_LOCATION_CENTER;
	_random_spot_size = _random_spot select XF_MAP_LOCATION_SIZE;
	if (_random_spot_size > 250) then { _random_spot_size = 250; };

	_conquer_updated = false;
	_hq_updated = false;
	_artillery_updated = false;
	_enemy_initial_counts = ([_random_spot_pos,_random_spot_size,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
	_last_reinforcement = -600;
	
	// We will make the number and the power of Paradrops dependent on the number of players.
	_reinforcements = 1; // How many reinforcements will be triggered at max.
	_reinforcement_power = 1; // How many vehicles per reinforcement will be spawned.
	_num_players = call XPlayersNumber;
	switch (true) do {
		case (_num_players <= 2): { _reinforcements = 2; _reinforcement_power = 1;};
		case (_num_players <= 5): { _reinforcements = 3; _reinforcement_power = 1;};
		case (_num_players <= 8): { _reinforcements = 4; _reinforcement_power = 1;};
		case (_num_players <= 12): { _reinforcements = 3; _reinforcement_power = 2;};
		case (_num_players <= 15): { _reinforcements = 4; _reinforcement_power = 2;};
		default {_reinforcements = 5; _reinforcement_power = 2;};
	};
	_reinforcements = _reinforcements + DM_Mission_RandomReinforcement;
	_reinforcement_power = _reinforcement_power max (DM_Mission_RandomReinforcement / 2);
	
	diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Entering the loop",DM_Mission_ArtilleryVariables, Time];
	while {DM_Mission_Chapter_CanRun AND DM_Mission_Mission_CanRun} do {
		sleep 10;
		_enemy_counts = ([_random_spot_pos,_random_spot_size,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
		_castle_clear = ["jip_spot_clear",false] call XNetGetJIP;
		_hq_destroyed = ["jip_hq_destroyed",false] call XNetGetJIP;
		// We check how many enemies did die already.
		_enemy_diff = _enemy_initial_counts - _enemy_counts;
		// We check if all artillery are destroyed or not.
		_artillery_destroyed = True;
		{
			_destroyed = [_x,False] call XNetGetJIP;
			if (!_destroyed) exitWith {_artillery_destroyed = False;};
		} foreach DM_Mission_ArtilleryVariables;
		
		//diag_log Format["(%1)[%2]: %3: %4, %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute",_enemy_diff,_castle_clear,_artillery_destroyed,_hq_destroyed];
		if (_castle_clear and !_conquer_updated) then {
			["KillTheEnemies","Search N Destroy", "","",[],"Succeeded"] call XfMissionTask;
			_conquer_updated = true;
		};
		if (_artillery_destroyed and !_artillery_updated) then {
			["DestroyTheArtillery","Destroy The Artillery", "","",[],"Succeeded"] call XfMissionTask;
			_artillery_updated = true;
		};
		If (_hq_destroyed and !_hq_updated) then {
			["DestroyTheHQ","Destroy the enemy HQ", "","",[],"Succeeded"] call XfMissionTask;
			_hq_updated = true;
			_reinforcements = 0;
		};
		// We check that the HQ is destroyed, that the artillery is destroyed and that we didn't call any reinforcement in the last 5 minutes (which is normally enough for them to arrive)
		If (_hq_destroyed and _castle_clear and _artillery_destroyed) then {
			_chapter_succeeded = true;
			DM_Mission_Chapter_CanRun = false;
			sleep 10;
		};
		If (DM_Mission_Chapter_CanRun AND (_reinforcements > 0)) then {
			// If a third of the defenders are dead... and there are more than 8 defenders left...
			// Then we send new troops in :)
			if ((_enemy_diff > (_enemy_initial_counts /3)) && (_enemy_counts >= 8)) then {
				// If the reinforcement function returns a value greater than 0, it means a reinforcement was created!
				if (([d_enemy_side,[_random_spot_pos,50],_reinforcement_power] call XfMissionRandomReinforcement) > 0) then {
					diag_log Format["(%1)[%2]: %3: %4: reinf:%5, diff:%6, ini:%7, vec:%8",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Sending reinforcement",_reinforcements,_enemy_diff,_enemy_initial_counts];
					_reinforcements = _reinforcements - 1;
					hint "Reinforcement";
				};
			};
		};
	};
	if (DM_Mission_Mission_CanRun) then {
		if (_chapter_succeeded) then {
			call XfMissionChapterSuccess;
		} else {
			call XfMissionChapterFailure;
		};
	} else {
		diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Mission canceled!"];
	};
	_players_found = true;
	_enemy_count = 100;
	While {DM_Mission_Mission_CanRun && _enemy_count > 1 && _players_found} do {
		sleep 5;
		if (X_MP) then {
			_players_found = false;
			{
				if (([(getPos _x), _random_spot_pos, _random_spot_size * 2] call XfPointInCircle) && isplayer _x) exitWith { _players_found = true; };
			} foreach playableUnits;
		} else {
			_players_found = ([(getPos player), _random_spot_pos, _random_spot_size * 2] call XfPointInCircle);
		};
		_enemy_count = (([_random_spot_pos,(_random_spot_size * 2),d_enemy_side] call XfMissionGetZoneSideCount) select 0);
		if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3: %4: player:%5  enemies:%6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Chapter End Check",_players_found,_enemy_count]; };
	};
	// Just in case a reinforcement is already on the way.
	call XfMissionCancelReinforcement;
	call XfMissionChapterCleanUp;
	DM_Mission_Chapter_Runs = False;
};

XfMissionChapterSetup={
	private ["_random_spot","_random_spot_pos","_random_spot_size","_troops_power","_troops_coeff","_grpSpecOps1","_grpSpecOps2","_i"];
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Starting Initialization"];
	
	// Between 1 and 4 artillery
	_artillery_count = (1 + floor(random 3));
	_artillery_positions = [];
	
	_random_spot = [];
	_random_spot_pos = [];
	_random_spot_size = 200;
	_building = objNull;
	_i_tries = 30;
	diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Starting to search spots",_artillery_count];
	while { count _random_spot <= 0 && _i_tries > 0 } do {
		_random_spot = [[XF_MAP_LOCATION_TYPE_MILITARY,XF_MAP_LOCATION_TYPE_MOUNTAIN]] call XfMissionGetRandomSpot;
		diag_log "";
		diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Checking Spot",_random_spot];
		if (count _random_spot > 0) then {
			_random_spot_pos = _random_spot select XF_MAP_LOCATION_CENTER;
			_random_spot_size = _random_spot select XF_MAP_LOCATION_SIZE;
			if (_random_spot_size < 150) then { _random_spot_size = 150; };
			// We take one position too much, it will serve for the HQ
			for [{_i = 0},{_i <= _artillery_count},{_i = _i + 1}] do {
				_random_point = [];
				_i_tries2 = 30;
				while { ((count _random_point) <= 0) && _i_tries2 > 0} do {
					// We don't want the artillery on the border of the zone.
					_random_point = [_random_spot_pos, (_random_spot_size * 0.7)] call XfGetRanPointCircleBig;
					diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Testing Pos",_random_point];
					_too_close = false;
					{
						if ((_x distance _random_point) < 30) then {
							diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Too close",(_x distance _random_point)];
							_too_close = true;
						};
					} foreach _artillery_positions;
					if (_too_close) then { _random_point = []; };
					_i_tries2 = _i_tries2 - 1;
				};
				if (count _random_point < 3) exitWith {diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Missing an artillery spot"];};
				diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Adding Spot",_random_point];
				_artillery_positions set [ count _artillery_positions, _random_point];
			};
			if ((count _artillery_positions) >= _artillery_count) then {
			
			} else {
				_artillery_positions = [];
				_random_spot = [];
			};
		};
		_i_tries = _i_tries - 1;
	};
	if ((count _random_spot) <= 0) exitWith {"STR_MF_RANDOMSITEFAILED" call XfMissionMessageToAll; DM_Mission_Mission_CanRun = false; DM_Mission_Chapter_CanRun = false;};
	_random_spot_name = _random_spot select XF_MAP_LOCATION_DISPLAYNAME;
	diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Artillery Spots",_artillery_positions];

	DM_Chapter_Location = _random_spot;
	DM_Chapter_Position = _random_spot_pos;
	
	if (_random_spot_size > 250) then { _random_spot_size = 250; };
	
	[_random_spot_pos,_random_spot_size,_random_spot_name] call XfMissionCurrentPosition;
	
	_teleporter = [_random_spot_pos] call XfMissionRandomStartTeleporter;
	// If no spot found, we get back an empty position.
	if (count (_teleporter select 0) > 0) then {
		[false,["chapter1_start_position",(_teleporter select 0), "ICON", "ColorBlue", [1,1],"",(_teleporter select 1),"hd_start","",1]] call XfMissionMarker;
	};

	// The marker which indicates the war zone	
	[false,["chapter1_camp_zone", _random_spot_pos, "ELLIPSE", "ColorRed", [(_random_spot_size * 1.5),(_random_spot_size * 1.5)],"",0,"","BDiagonal",0.5]] call XfMissionMarker;
	[false,["chapter1_camp_position",_random_spot_pos, "ICON", "ColorRed", [1,1],_random_spot_name,0,"hd_objective","",0.6]] call XfMissionMarker;
	// To logic to dynamically change the number of enemy units depending on the player count.

	// We create 1 to 4 artillery and flag them as destroy objects.
	for [{_i = 0},{_i < _artillery_count},{_i = _i + 1}] do {
		// We dynamically create a variable name which will be stored in the Global array and used to check the success status.
		_jip_var = format["jip_destroy_artillery_%1",_i];
		[_jip_var,False] call XNetSetJIP;
		_pos = (_artillery_positions select _i);
		_arty = ["D30_Ins",[_pos,floor(random 360)],"DESTROY",["STR_MF_M_ARTILLERY_DESTROYED",_jip_var,True,1,["PipeBomb"]]] call XfMissionCreateMissionObject;
		// We lock them for safety :-)
		_arty lock true;
		[false,[format["chapter1_%1",_jip_var],_pos, "ICON", "ColorRed", [0.6,0.6],"",0,"hd_objective","",0.8]] call XfMissionMarker;
		DM_Mission_ArtilleryVariables set [count DM_Mission_ArtilleryVariables, _jip_var];
	};
	
	["jip_hq_destroyed",false] call XNetSetJIP;
	// This line spawns an unfolded BTR90 HQ like a real base :)
	_HQ_Pos = (_artillery_positions select ((count _artillery_positions) - 1));
	// diag_log Format["(%1)[%2]: %3; %4: %5 %6 %7",diag_tickTime,"chapter1.sqf","XfMissionChapterSuccess","HQ POS",_HQ_Pos,(count _artillery_positions),_artillery_positions];
	["BTR90_HQ_unfolded",[_HQ_Pos,floor(random 360)],"DESTROY",["STR_MF_M_ARTILLERY_PCDESTROYED","jip_hq_destroyed",True,1,["PipeBomb","R_M136_AT","R_SMAW_HEAA","R_SMAW_HEDP","M_Javelin_AT","R_PG7V_AT","R_PG7VL_AT","R_PG7VR_AT","R_OG7_AT","M_Strela_AA","R_RPG18_AT","M_AT13_AT","M_Igla_AA"]]] call XfMissionCreateMissionObject;
	["DestroyTheHQ","STR_MF_M_ARTILLERY_TASK_DESTROYHQ", "STR_MF_M_ARTILLERY_TASK_DESTROYHQ_DESC","",[],"Created"] call XfMissionTask;
	
	[d_enemy_side,[_random_spot_pos,_random_spot_size],true] call XfMissionPopulateLocation;
	
	// We now create the "object" which is used to create the zone to conquer. It serves as a variable holder more than anything.
	["jip_spot_clear",false] call XNetSetJIP;
	["HeliHEmpty",_random_spot_pos,"CONQUER",["STR_MF_M_ARTILLERY_CAMPCLEAR",[_random_spot_pos, [(_random_spot_size * 2.5),(_random_spot_size * 2.5)], 0, false],d_enemy_side,"jip_spot_clear"]] call XfMissionCreateMissionObject;
	["KillTheEnemies","STR_MF_M_ARTILLERY_SND", "STR_MF_M_ARTILLERY_SND_DESC","",[],"Created"] call XfMissionTask;
	["DestroyTheArtillery","STR_MF_M_ARTILLERY_TASK_ARTI", "STR_MF_M_ARTILLERY_TASK_ARTI_DESC","",[],"Created"] call XfMissionTask;
	
	// This will create snipers automatically if selected in the mission setup
	[d_enemy_side,[_random_spot_pos,_random_spot_size],DM_Mission_Snipers] call XfMissionCreateSnipersArea;
	// This will create air support automatically if selected in the mission setup
	[d_enemy_side,[_random_spot_pos,_random_spot_size],DM_Mission_AirSupport] call XfMissionCallAirSupport;
};

XfMissionChapterSuccess={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSuccess","Starting"];
	DM_Mission_Chapter_Success = 1;
};

XfMissionChapterFailure={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterFailure","Starting"];
	DM_Mission_Chapter_Success = -1;
};

// Self-explanatory
XfMissionChapterCleanUp={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterCleanUp","Starting"];
	// Giving an empty position places the teleporter back to the hangar, closing the hangar.
	[[],0] call XfMissionPlaceStartTeleporter;
	[] call XfMissionCleanMarkers;
	[] call XfMissionCleanTriggers;
	[] call XfMissionCleanTasks;
};

DM_Mission_Chapter_Compiled = true;